<!DOCTYPE html>
<html lang=zh>
<head>
    <meta charset="utf-8">
    
    <title>1-redis-好-使用场景 | johnny技术地</title>
    
    
        <meta name="keywords" content="redis" />
    
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
    <meta name="description" content="redisRedis 定位是一个内存数据库，正是由于内存的快速访问特性，才使得Redis能够有如此高的性能，才使得Redis能够轻松处理大量复杂的数据结构 缓存只是他最简单和基础的功能罢了，哨兵，集群，分布式锁，延时队列，位图，HyperLogLog，布隆过滤器，限流，GeoHash（附近的人） 知识点脑图    分布式锁为什么需要分布式锁多系统写作，竞争共享资源，难免就要了 怎样实现分布式锁本质">
<meta property="og:type" content="article">
<meta property="og:title" content="1-redis-好-使用场景">
<meta property="og:url" content="https://abcd_1101.gitee.io/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/1-redis-%E5%A5%BD-%E4%BD%BF%E7%94%A8%E5%9C%BA%E6%99%AF/index.html">
<meta property="og:site_name" content="johnny技术地">
<meta property="og:description" content="redisRedis 定位是一个内存数据库，正是由于内存的快速访问特性，才使得Redis能够有如此高的性能，才使得Redis能够轻松处理大量复杂的数据结构 缓存只是他最简单和基础的功能罢了，哨兵，集群，分布式锁，延时队列，位图，HyperLogLog，布隆过滤器，限流，GeoHash（附近的人） 知识点脑图    分布式锁为什么需要分布式锁多系统写作，竞争共享资源，难免就要了 怎样实现分布式锁本质">
<meta property="og:locale">
<meta property="og:image" content="https://abcd_1101.gitee.io/gitee-internal-blog/images/redis-知识点脑图.jpg">
<meta property="article:published_time" content="2021-09-04T08:06:22.000Z">
<meta property="article:modified_time" content="2021-10-17T08:04:41.472Z">
<meta property="article:author" content="Johnny">
<meta property="article:tag" content="redis">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://abcd_1101.gitee.io/gitee-internal-blog/images/redis-知识点脑图.jpg">
    

    
        <link rel="alternate" href="/atom.xml" title="johnny技术地" type="application/atom+xml" />
    

    
        <link rel="icon" href="/gitee-internal-blog/favicon.ico" />
    

    
<link rel="stylesheet" href="/gitee-internal-blog/libs/font-awesome/css/font-awesome.min.css">

    
<link rel="stylesheet" href="/gitee-internal-blog/libs/open-sans/styles.css">

    
<link rel="stylesheet" href="/gitee-internal-blog/libs/source-code-pro/styles.css">


    
<link rel="stylesheet" href="/gitee-internal-blog/css/style.css">

    
<script src="/gitee-internal-blog/libs/jquery/2.1.3/jquery.min.js"></script>

    
<script src="/gitee-internal-blog/libs/jquery/plugins/cookie/1.4.1/jquery.cookie.js"></script>

    
    
        
<link rel="stylesheet" href="/gitee-internal-blog/libs/lightgallery/css/lightgallery.min.css">

    
    
        
<link rel="stylesheet" href="/gitee-internal-blog/libs/justified-gallery/justifiedGallery.min.css">

    
    
    
    


    
        <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
    
<meta name="generator" content="Hexo 5.4.0"></head>

<body>
    <div id="container">
        <header id="header">
    <div id="header-main" class="header-inner">
        <div class="outer">
            <a href="/gitee-internal-blog/" id="logo">
                <i class="logo"></i>
                <span class="site-title">johnny技术地</span>
            </a>
            <nav id="main-nav">
                
                    <a class="main-nav-link" href="/gitee-internal-blog/">首页</a>
                
                    <a class="main-nav-link" href="/gitee-internal-blog/archives">归档</a>
                
                    <a class="main-nav-link" href="/gitee-internal-blog/categories">分类</a>
                
                    <a class="main-nav-link" href="/gitee-internal-blog/tags">标签</a>
                
                    <a class="main-nav-link" href="/gitee-internal-blog/about">关于</a>
                
            </nav>
            
            <div id="search-form-wrap">

    <form class="search-form">
        <input type="text" class="ins-search-input search-form-input" placeholder="Search" />
        <button type="submit" class="search-form-submit"></button>
    </form>
    <div class="ins-search">
    <div class="ins-search-mask"></div>
    <div class="ins-search-container">
        <div class="ins-input-wrapper">
            <input type="text" class="ins-search-input" placeholder="Type something..." />
            <span class="ins-close ins-selectable"><i class="fa fa-times-circle"></i></span>
        </div>
        <div class="ins-section-wrapper">
            <div class="ins-section-container"></div>
        </div>
    </div>
</div>
<script>
(function (window) {
    var INSIGHT_CONFIG = {
        TRANSLATION: {
            POSTS: 'Posts',
            PAGES: 'Pages',
            CATEGORIES: 'Categories',
            TAGS: 'Tags',
            UNTITLED: '(Untitled)',
        },
        ROOT_URL: '/gitee-internal-blog/',
        CONTENT_URL: '/gitee-internal-blog/content.json',
    };
    window.INSIGHT_CONFIG = INSIGHT_CONFIG;
})(window);
</script>

<script src="/gitee-internal-blog/js/insight.js"></script>


</div>
        </div>
    </div>
    <div id="main-nav-mobile" class="header-sub header-inner">
        <table class="menu outer">
            <tr>
                
                    <td><a class="main-nav-link" href="/gitee-internal-blog/">首页</a></td>
                
                    <td><a class="main-nav-link" href="/gitee-internal-blog/archives">归档</a></td>
                
                    <td><a class="main-nav-link" href="/gitee-internal-blog/categories">分类</a></td>
                
                    <td><a class="main-nav-link" href="/gitee-internal-blog/tags">标签</a></td>
                
                    <td><a class="main-nav-link" href="/gitee-internal-blog/about">关于</a></td>
                
                <td>
                    
    <div class="search-form">
        <input type="text" class="ins-search-input search-form-input" placeholder="Search" />
    </div>

                </td>
            </tr>
        </table>
    </div>
</header>

        <div class="outer">
            
            
                <aside id="sidebar">
   
        
    <div class="widget-wrap" id='categories'>
        <h3 class="widget-title">
            <span>categories</span>
            &nbsp;
            <a id='allExpand' href="#">
                <i class="fa fa-angle-double-down fa-2x"></i>
            </a>
        </h3>
        
        
        
         <ul class="unstyled" id="tree" > 
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            DLT
                        </a>
                         <ul class="unstyled" id="tree" > 
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            Ledger
                        </a>
                         <ul class="unstyled" id="tree" > 
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            Corda
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2023/03/09/DLT/Ledger/Corda/Corda%E4%BE%8B%E5%AD%90/">Corda例子</a></li>  </ul> 
                    </li> 
                     </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            概念和框架
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2023/02/04/DLT/%E6%A6%82%E5%BF%B5%E5%92%8C%E6%A1%86%E6%9E%B6/%E5%8C%BA%E5%9D%97%E9%93%BE%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80/">区块链理论基础</a></li>  </ul> 
                    </li> 
                     </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            IDE
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/05/03/IDE-eclipse-debug-f5-8/">IDE eclipse debug f5-8</a></li>  </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            docker_k8s
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/06/19/docker_k8s/springcloud%20vs%20k8s/"></a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/06/docker_k8s/%E5%AE%B9%E5%99%A8-docker-k8s/">容器-docker-k8s</a></li>  </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            git
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/04/05/git-reset-and-revert/">git reset and revert</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/04/14/git-pull-request-to-contribute-other-project/">Pull request to contribute other project</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/04/18/git-stash%E7%94%A8%E6%B3%95/">git stash用法</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/05/16/git-tag%E8%AE%B0%E5%BD%95%E7%89%88%E6%9C%AC%E5%AF%B9%E5%BA%94commit/">git tag记录版本对应commit</a></li>  </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            java
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/04/25/java%E5%9F%BA%E7%A1%801/">java基础1</a></li>  </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            jvm
                        </a>
                         <ul class="unstyled" id="tree" > 
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            性能监测
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/04/11/jvisualvm%E5%92%8Csprintboot%20admin%E6%80%A7%E8%83%BD%E7%9B%91%E6%B5%8B/">jvisualvm和sprintboot admin性能监测</a></li>  </ul> 
                    </li> 
                     </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            linux
                        </a>
                         <ul class="unstyled" id="tree" > 
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            常用命令
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/04/11/linux%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/">linux常用命令</a></li>  </ul> 
                    </li> 
                     <li class="file"><a href="/gitee-internal-blog/2021/04/18/linux-find%E5%91%BD%E4%BB%A4/">linux-find命令</a></li>  </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            spring
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/05/01/spring-log%E6%97%A5%E5%BF%97%E8%AE%B0%E5%BD%95/">日志记录</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/05/03/spring-mvc%E5%BF%85%E5%A4%87%E9%85%8D%E7%BD%AE/">spring mvc必备配置</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/05/23/spring%E8%84%9A%E6%89%8B%E6%9E%B6%E5%8E%9F%E7%90%86/">spring脚手架原理</a></li>  </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            windows
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/04/17/windows-dns%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%9C%AA%E5%93%8D%E5%BA%94/">windows dns服务器未响应</a></li>  </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            中间件
                        </a>
                         <ul class="unstyled" id="tree" > 
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            mq
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/06/25/%E4%B8%AD%E9%97%B4%E4%BB%B6/mq/2-mq%E9%87%8D%E5%A4%8D%E9%A1%BA%E5%BA%8F%E6%B6%88%E8%B4%B9/">2-mq重复顺序消费</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E4%B8%AD%E9%97%B4%E4%BB%B6/mq/1-mq%E5%9F%BA%E7%A1%80/">1-mq基础</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E4%B8%AD%E9%97%B4%E4%BB%B6/mq/0-mq-zookeeper%E6%98%AF%E4%BB%80%E4%B9%88/">0-mq-zookeeper是什么</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E4%B8%AD%E9%97%B4%E4%BB%B6/mq/3-mq-kafka%E5%85%A5%E9%97%A8/">3-mq-kafka入门</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E4%B8%AD%E9%97%B4%E4%BB%B6/mq/4-mq%E9%97%AE%E9%A2%98%E4%B8%8D%E4%B8%A2%E5%A4%B1-%E9%87%8D%E5%A4%8D-%E6%9C%89%E5%BA%8F-%E5%A0%86%E7%A7%AF/">4-mq问题不丢失_重复_有序_堆积</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/05/%E4%B8%AD%E9%97%B4%E4%BB%B6/mq/5-mq-kafka-segement%E8%AF%BB%E5%86%99/">5-mq-kafka-segement读写</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/07/%E4%B8%AD%E9%97%B4%E4%BB%B6/mq/6-mq-kafka%E4%B8%89%E8%BF%9E%E5%87%BB/">6-mq-kafka三连击</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/12/%E4%B8%AD%E9%97%B4%E4%BB%B6/mq/7-mq-kafka%E6%98%AF%E6%8E%A8%E8%BF%98%E6%98%AF%E6%8B%89/">7-mq-kafka是推还是拉</a></li>  </ul> 
                    </li> 
                     </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            必会框架
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/09/06/%E5%BF%85%E4%BC%9A%E6%A1%86%E6%9E%B6/%E6%A1%86%E6%9E%B6-%E9%AB%98%E6%80%A7%E8%83%BDNIO-Netty/">框架-高性能NIO-Netty</a></li>  </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            操作系统
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/09/06/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F-pageCache/">操作系统-pageCache</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/06/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F-nioFilechannel%E5%A0%86%E5%A4%96directBuffer%E4%B8%8E%E5%A0%86%E5%86%85byteBuffer/">操作系统-nioFilechannel堆外directBuffer与堆内byteBufferbyteBuffer</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/06/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F-%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E4%BC%98%E5%8C%96%E6%8F%A1%E6%89%8B%E6%8C%A5%E6%89%8B/">操作系统-计算机网络优化握手挥手</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/06/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F-%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E5%B8%B8%E9%97%AE/">操作系统-计算机网络常问</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/06/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F-%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E6%8A%93%E5%8C%85/">操作系统-计算机网络抓包</a></li>  </ul> 
                    </li> 
                    
                    <li class="directory open">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder-open"></i>
                            &nbsp;
                            数据库
                        </a>
                         <ul class="unstyled" id="tree" > 
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            mysql
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/0-mysql%E7%BB%93%E6%9E%84%E4%B8%8E%E6%8F%92%E5%85%A5/">0-mysql结构与插入</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/1-mysql%E4%B8%80%E8%87%B4%E6%80%A7%E8%AF%BB-%E4%BA%8B%E5%8A%A1%E5%9B%9E%E6%BB%9A-mvcc/">1-mysql一致性读-事务回滚-mvcc</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/3-mysql-sql%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%E5%AE%8F%E8%A7%82%E6%B5%81%E7%A8%8B-redo-undo-bin/">3-mysql-sql执行过程宏观流程-redo-undo-bin</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/5-mysql-sql%E8%B0%83%E4%BC%98%E6%80%9D%E8%B7%AF/">5-mysql-sql调优思路</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/4-mysql-explain%E6%89%A7%E8%A1%8C%E5%85%B7%E4%BD%93%E6%B5%81%E7%A8%8B/">4-mysql-explain执行具体流程</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/6-mysql-%E7%B4%A2%E5%BC%95%E4%BD%9C%E7%94%A8%E5%92%8C%E8%AE%BE%E8%AE%A1/">6-mysql-索引作用和设计</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/8-mysql-%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E6%B1%A0%E8%AE%BE%E5%A4%9A%E5%A4%A7/">8-mysql-数据库连接池设多大</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/9-mysql-%E4%BB%8E%E4%B8%9A%E5%8A%A1%E5%88%B0%E6%95%B0%E6%8D%AE%E5%BA%93%E8%AE%BE%E8%AE%A1-%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B/">9-mysql-从业务到数据库设计-软件工程</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/7-mysql-changebuffer-merge/">7-mysql-changebuffer-merge</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/2-mysql-undo-purge_bin_redo-flush%E8%84%8F%E9%A1%B5/">2-mysql-undo-purge_bin_redo-flush脏页</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/10-mysql-mysql8%E6%96%B0%E7%89%B9%E6%80%A7/">10-mysql-mysql8新特性</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/12-mysql-%E5%85%A8%E5%B1%80%E9%94%81-%E8%A1%A8%E9%94%81-%E8%A1%8C%E9%94%81/">12-mysql-全局锁-表锁-行锁</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/11-mysql-%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6%E5%92%8C%E5%AE%9E%E6%88%98/">11-mysql-主从复制和实战</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/13-mysql-%E6%9E%B6%E6%9E%84%E6%96%B9%E6%A1%88/">13-mysql-架构方案</a></li>  </ul> 
                    </li> 
                    
                    <li class="directory open">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder-open"></i>
                            &nbsp;
                            redis
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/8-redis-%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E6%93%8D%E4%BD%9C/">8-redis-数据结构和操作</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/11-redis-%E5%8F%AF%E7%94%A8%E6%80%A7-mysql%E4%B8%80%E8%87%B4%E6%80%A7%E9%97%AE%E9%A2%98/">11-redis-可用性-mysql一致性问题</a></li>  <li class="file active"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/1-redis-%E5%A5%BD-%E4%BD%BF%E7%94%A8%E5%9C%BA%E6%99%AF/">1-redis-好-使用场景</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/2-redis-%E5%BF%AB-%E5%86%85%E5%AD%98%E8%80%97%E5%B0%BD%E5%90%8E%E4%BC%9A%E6%80%8E%E6%A0%B7/">2-redis-快-内存耗尽后会怎样</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/3-redis-%E5%BF%AB-%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E6%93%8D%E4%BD%9C/">3-redis-快-数据结构和操作</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/4-redis-%E5%BF%AB-%E4%B8%BA%E4%BD%95%E5%8F%98%E5%A4%9A%E7%BA%BF%E7%A8%8B/">4-redis-快-为何变多线程</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/7-redis-%E4%BC%98%E5%8C%96-%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5/"></a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/8-redis-%E4%BC%98%E5%8C%96-%E9%9B%AA%E5%B4%A9-%E7%A9%BF%E9%80%8F-%E5%87%BB%E7%A9%BF/">8-redis-优化-雪崩-穿透-击穿</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/9-redis-%E5%8F%AF%E7%94%A8%E6%80%A7-%E6%8C%81%E4%B9%85%E5%8C%96/">9-redis-可用性-持久化</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/20-redis-%E9%9D%A2%E8%AF%95%E9%A2%98/">20-redis-面试题</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/5-redis-%E5%BF%AB-%E5%A4%9A%E8%B7%AFio%E5%A4%8D%E7%94%A8/">5-redis-快-多路io复用</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/6-redis-%E4%BC%98%E5%8C%96-%E5%8F%98%E6%85%A2%E4%BA%86%E5%90%97/">6-redis-优化-变慢了吗</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/10-redis-%E5%8F%AF%E7%94%A8%E6%80%A7-%E9%9B%86%E7%BE%A4%E7%AF%87/">10-redis-可用性-集群篇</a></li>  </ul> 
                    </li> 
                     </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            知识点框架
                        </a>
                         <ul class="unstyled" id="tree" > 
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            19-数据库
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/08/02/19-1-Oracle%E5%B8%B8%E8%80%83/">19-1-Oracle常考</a></li>  </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            2-jvm
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/06/25/2-1-JVM%E8%84%91%E5%9B%BE/">2-1-JVM脑图</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/06/25/2-2-JVM%E5%86%85%E5%AD%98%E5%8C%BA%E5%9F%9F/">2-2-JVM内存区域</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/06/26/2-3-jvm%E8%BF%90%E8%A1%8C%E6%97%B6%E5%86%85%E5%AD%98/">2-3-jvm运行时内存</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/06/26/2-4-%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6-%E7%AE%97%E6%B3%95-%E9%80%83%E9%80%B8%E5%88%86%E6%9E%90/">2-4-垃圾回收-算法-逃逸分析</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/06/27/2-5-java%E5%9B%9B%E7%A7%8D%E5%BC%95%E7%94%A8%E7%B1%BB%E5%9E%8B/">2-5-java四种引用类型</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/06/28/2-6-7-gc%E7%AE%97%E6%B3%95%E5%92%8C%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8/">2-6-7-gc算法和垃圾收集器</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/06/28/2-8-java-io-and-nio/">2-8-java io and nio</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/06/29/2-9-jvm%E7%B1%BB%E5%8A%A0%E8%BD%BD%E6%9C%BA%E5%88%B6/">2-9-jvm类加载机制</a></li>  </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            3-java集合
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/06/30/3-1-java%E6%8E%A5%E5%8F%A3%E7%BB%A7%E6%89%BF%E5%85%B3%E7%B3%BB%E4%B8%8E%E5%AE%9E%E7%8E%B0/">3-1-java接口继承关系与实现</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/06/30/3-2-List/">3-2-List</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/01/3-3-Set/">3-3-Set</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/01/3-4-Map%E6%98%A0%E5%B0%84/">3-4-Map映射</a></li>  </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            4-java多线程
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/07/02/4-1-2-%E5%A4%9A%E7%BA%BF%E7%A8%8B%E8%84%91%E5%9B%BE%E5%92%8C%E5%9B%9B%E7%A7%8D%E7%BA%BF%E7%A8%8B%E5%88%9B%E5%BB%BA%E6%96%B9%E6%B3%95/">4-1-2-多线程脑图和四种线程创建</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/02/4-3-4%E7%A7%8D%E7%BA%BF%E7%A8%8B%E6%B1%A0/">4-3-4种线程池</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/02/4-4-%E7%BA%BF%E7%A8%8B%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F5%E7%A7%8D%E7%8A%B6%E6%80%81/">4-4-线程生命周期5种状态</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/02/4-5-%E7%BB%88%E6%AD%A2%E7%BA%BF%E7%A8%8B4%E6%96%B9%E5%BC%8F/">4-5-终止线程4方式</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/02/4-6-7-sleep%E4%B8%8Ewait-start%E4%B8%8Erun/">4-6-7-sleep与wait-start与run</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/03/4-8-java%E5%90%8E%E5%8F%B0%E7%BA%BF%E7%A8%8B/">4-8-java后台线程</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/03/4-9-java%E9%94%81/">4-9-java锁</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/05/4-10-%E7%BA%BF%E7%A8%8B%E5%9F%BA%E6%9C%AC%E6%96%B9%E6%B3%95/">4-10-线程基本方法</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/06/4-11-%E7%BA%BF%E7%A8%8B%E4%B8%8A%E4%B8%8B%E6%96%87%E5%88%87%E6%8D%A2/">4-11-线程上下文切换</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/06/4-12-%E5%90%8C%E6%AD%A5%E9%94%81%E4%B8%8E%E6%AD%BB%E9%94%81/">4-12-同步锁与死锁</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/06/4-13-%E7%BA%BF%E7%A8%8B%E6%B1%A0%E5%8E%9F%E7%90%86/">4-13-线程池原理</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/08/4-14-%E9%98%BB%E5%A1%9E%E9%98%9F%E5%88%97/">4-14-阻塞队列</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/10/4-15-cyclicBarrier-countdownlatch-semaphore/">4-15-cyclicBarrier-countdownlatch-semaphore</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/14/4-16-volatile%E5%85%B3%E9%94%AE%E5%AD%97%E4%BD%9C%E7%94%A8/">4-16-volatile关键字作用</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/14/4-17-%E4%B8%A4%E4%B8%AA%E7%BA%BF%E7%A8%8B%E5%85%B1%E4%BA%AB%E6%95%B0%E6%8D%AE/">4-17-两个线程共享数据</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/16/4-18-ThreadLocal%E4%BD%9C%E7%94%A8/">4-18-ThreadLocal作用</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/16/4-19-synchronized%E5%92%8Creentrantlock%E5%8C%BA%E5%88%AB/">4-19-synchronized和reentrantlock区别</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/17/4-20-ConcurrentHashMap/">4-20-ConcurrentHashMap</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/17/4-21-22-java%E7%BA%BF%E7%A8%8B%E8%B0%83%E5%BA%A6%E5%92%8C%E7%AE%97%E6%B3%95/">4-21-22-java线程调度和算法</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/17/4-23-cas%E6%AF%94%E8%BE%83%E5%B9%B6%E4%BA%A4%E6%8D%A2/">4-23-cas比较并交换</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/17/4-24-aqs%E6%8A%BD%E8%B1%A1%E7%9A%84%E9%98%9F%E5%88%97%E5%90%8C%E6%AD%A5%E5%99%A8/">4-24-aqs抽象的队列同步器</a></li>  </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            5-java基础
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/07/19/5-1-exception%E5%BC%82%E5%B8%B8%E5%88%86%E7%B1%BB%E5%8F%8A%E5%A4%84%E7%90%86/">5-1-exception异常分类及处理</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/20/5-2-java%E5%8F%8D%E5%B0%84/">5-2-java反射</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/22/5-3-java%E6%B3%A8%E8%A7%A3annotation/">5-3-java注解annotation</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/24/5-4-java%E5%86%85%E9%83%A8%E7%B1%BB/">5-4-java内部类</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/08/14/5-5-jdk8-lambda/">5-5-jdk8-lambda</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/08/14/5-6-RxJava/">5-6-RxJava</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/08/14/5-7-java-Observer%E6%8E%A5%E5%8F%A3%E5%92%8CObservable%E7%B1%BB/">5-7-java-Observer接口和Observable类</a></li>  </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            6-spring
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/05/03/6-2-springboot%E5%B8%B8%E8%80%83/">6-2-springboot常考</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/31/6-1-spring%E5%B8%B8%E8%80%83/">6-1-spring常考</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/08/28/6-3-springcloud%E7%94%A8%E8%BF%87%E7%9A%84/">6-3-springcloud用过的</a></li>  </ul> 
                    </li> 
                     </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            面试的项目实现
                        </a>
                         <ul class="unstyled" id="tree" > 
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            中间件
                        </a>
                         <ul class="unstyled" id="tree" > 
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            es
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/06/25/%E4%B8%AD%E9%97%B4%E4%BB%B6/es/es/">es</a></li>  </ul> 
                    </li> 
                     </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            微服务
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/08/21/%E9%9D%A2%E8%AF%95%E7%9A%84%E9%A1%B9%E7%9B%AE%E5%AE%9E%E7%8E%B0/%E5%BE%AE%E6%9C%8D%E5%8A%A1/hystrix/"></a></li>  </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            数据库
                        </a>
                         <ul class="unstyled" id="tree" > 
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            mysql
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/09/04/%E9%9D%A2%E8%AF%95%E7%9A%84%E9%A1%B9%E7%9B%AE%E5%AE%9E%E7%8E%B0/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/0-mysql%E7%BB%93%E6%9E%84%E4%B8%8E%E6%8F%92%E5%85%A5/">0-mysql结构与插入</a></li>  </ul> 
                    </li> 
                     </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            自动补全
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/06/25/%E9%9D%A2%E8%AF%95%E7%9A%84%E9%A1%B9%E7%9B%AE%E5%AE%9E%E7%8E%B0/%E8%87%AA%E5%8A%A8%E8%A1%A5%E5%85%A8/es%E8%87%AA%E5%8A%A8%E8%A1%A5%E5%85%A8/">es自动补全</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/08/21/%E9%9D%A2%E8%AF%95%E7%9A%84%E9%A1%B9%E7%9B%AE%E5%AE%9E%E7%8E%B0/%E8%87%AA%E5%8A%A8%E8%A1%A5%E5%85%A8/redis%E8%87%AA%E5%8A%A8%E8%A1%A5%E5%85%A8/"></a></li>  </ul> 
                    </li> 
                     <li class="file"><a href="/gitee-internal-blog/2021/06/25/%E9%9D%A2%E8%AF%95%E7%9A%84%E9%A1%B9%E7%9B%AE%E5%AE%9E%E7%8E%B0/IJP%E9%9D%A2%E8%AF%95%E9%A1%B9%E7%9B%AE%E5%AE%9E%E7%8E%B0/">IJP面试项目实现</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/06/25/%E9%9D%A2%E8%AF%95%E7%9A%84%E9%A1%B9%E7%9B%AE%E5%AE%9E%E7%8E%B0/Ex%E9%9D%A2%E8%AF%95%E9%A1%B9%E7%9B%AE%E5%AE%9E%E7%8E%B0/">Ex面试项目实现</a></li>  </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            面试题
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/06/25/%E9%9D%A2%E8%AF%95%E9%A2%98/SpringBoot+Tomcat+Nginx+Netty%E9%9D%A2%E8%AF%95%E9%A2%98/">SpringBoot+Tomcat+Nginx+Netty面试题</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/06/25/%E9%9D%A2%E8%AF%95%E9%A2%98/%E9%98%BF%E9%87%8C%E9%9D%A2%E8%AF%95%E4%BA%8C/">阿里面试题2</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/06/25/%E9%9D%A2%E8%AF%95%E9%A2%98/%E9%98%BF%E9%87%8C%E9%9D%A2%E8%AF%95%E4%B8%80/">阿里面试题1</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/08/16/%E9%9D%A2%E8%AF%95%E9%A2%98-java%E5%9F%BA%E7%A1%80%E9%9D%A2%E8%AF%9516%E9%97%AE/">面试题-java基础面试16问</a></li>  </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            项目经历
                        </a>
                         <ul class="unstyled" id="tree" > 
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            2019
                        </a>
                         <ul class="unstyled" id="tree" > 
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            xinge_notification
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/04/05/oracle_explain/">Oracle explain</a></li>  </ul> 
                    </li> 
                     </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            2021
                        </a>
                         <ul class="unstyled" id="tree" > 
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            房贷项目
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/04/05/%E9%A1%B9%E7%9B%AE%E4%BB%8E0%E5%88%B01/">项目从0到1</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/04/12/email-telnet-smtp-health-check/">email telnet smtp health check</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/04/12/%E5%8E%8B%E6%B5%8B%E5%8F%82%E6%95%B0%E6%8C%87%E6%A0%87/">压测参数指标</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/04/12/checkmarx%E5%AE%89%E5%85%A8%E6%89%AB%E6%8F%8F/">checkmarx安全扫描</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/04/25/db-table-annotation/">db table annotation</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/04/25/jdbctemplate-sql-injection/">jdbctemplate sql injection</a></li>  </ul> 
                    </li> 
                     </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            微信开发
                        </a>
                         <ul class="unstyled" id="tree" > 
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            安全
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/05/16/%E5%AE%89%E5%85%A8-java-ssl%E9%94%99%E8%AF%AF%E8%A7%A3%E5%86%B3%E7%A5%9E%E5%99%A8-net-debug%E5%8F%82%E6%95%B0/">安全-java ssl 错误解决神器 net debug参数</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/28/%E5%AE%89%E5%85%A8-%E5%8A%A0%E5%AF%86%E6%9C%BA/">安全-加密机</a></li>  </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            容器
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/07/28/%E6%9C%8D%E5%8A%A1%E5%99%A8/%E6%9C%8D%E5%8A%A1%E5%99%A8-IBM%20websphere%E7%BB%8F%E9%AA%8C%20-%20%E5%89%AF%E6%9C%AC/">服务器-IBM websphere经验</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/28/%E6%9C%8D%E5%8A%A1%E5%99%A8/%E6%9C%8D%E5%8A%A1%E5%99%A8-Tomcat%E7%BB%8F%E9%AA%8C/">服务器-Tomcat经验</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/07/28/%E6%9C%8D%E5%8A%A1%E5%99%A8/%E6%9C%8D%E5%8A%A1%E5%99%A8-IBM%20websphere%E7%BB%8F%E9%AA%8C/">服务器-IBM websphere经验</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/08/15/docker_k8s/%E5%AE%B9%E5%99%A8-k8s%E7%BD%91%E9%A1%B5%E5%B8%B8%E8%A7%81%E5%90%8D%E8%AF%8D/">容器-k8s网页常见名词</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/09/06/docker_k8s/%E5%AE%B9%E5%99%A8-Istio/">容器-Istio</a></li>  </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            小程序
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/05/16/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8FnavigateTo%E4%B8%8EredirectTo%E5%8C%BA%E5%88%AB/">小程序navigateTo与redirectTo区别</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/08/30/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F%E7%9A%84%E9%85%8D%E7%BD%AE/">微信小程序的配置</a></li>  </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            手机抓包
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/04/10/Fiddler%E5%AF%B9%E5%AE%89%E5%8D%93%E7%A7%BB%E5%8A%A8%E7%AB%AF%E7%9A%84%E6%8A%93%E5%8C%85%E6%B5%8B%E8%AF%95/">Fiddler对安卓移动端的抓包测试</a></li>  </ul> 
                    </li> 
                    
                    <li class="directory">
                        <a href="#" data-role="directory">
                            <i class="fa fa-folder"></i>
                            &nbsp;
                            高级群发系统
                        </a>
                         <ul class="unstyled" id="tree" >  <li class="file"><a href="/gitee-internal-blog/2021/05/09/Oracle-clob%E5%AD%97%E6%AE%B5/">Oracle clob字段</a></li>  </ul> 
                    </li> 
                     <li class="file"><a href="/gitee-internal-blog/2021/04/18/%E9%A1%B9%E7%9B%AE%E6%80%A7%E8%83%BD%E5%8F%82%E6%95%B0/">项目性能参数</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/05/09/%E5%BE%AE%E4%BF%A1%E6%8E%A5%E5%8F%A3%E6%B3%A8%E6%84%8F%E7%82%B9%E6%B1%87%E9%9B%86/">微信接口注意点汇集</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/05/09/%E5%BE%AE%E4%BF%A1%E4%B8%93%E7%BA%BF%E7%9A%84%E7%BD%91%E7%BB%9C%E5%B1%82%E7%90%86%E8%A7%A3/">专线的网络层理解</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/05/15/%E5%BE%AE%E4%BF%A1Sprint-plan/">Sprint plan</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/05/15/%E5%BE%AE%E4%BF%A1%E4%B8%8E%E9%93%B6%E8%81%94%E7%9A%84sso%E5%8D%95%E7%82%B9%E7%99%BB%E5%BD%95/">微信与银联的sso单点登录</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/05/22/G3%E8%87%AA%E5%8A%A8%E5%8C%96/">G3自动化</a></li>  <li class="file"><a href="/gitee-internal-blog/2021/05/29/%E5%BE%AE%E4%BF%A1%E9%A1%B9%E7%9B%AE%E5%BE%80ikp%E6%90%AC/">微信项目往ikp搬</a></li>  </ul> 
                    </li> 
                     </ul> 
                    </li> 
                     </ul> 
    </div>
    <script>
        $(document).ready(function() {
            var iconFolderOpenClass  = 'fa-folder-open';
            var iconFolderCloseClass = 'fa-folder';
            var iconAllExpandClass = 'fa-angle-double-down';
            var iconAllPackClass = 'fa-angle-double-up';
            // Handle directory-tree expansion:
            // 左键单独展开目录
            $(document).on('click', '#categories a[data-role="directory"]', function (event) {
                event.preventDefault();

                var icon = $(this).children('.fa');
                var expanded = icon.hasClass(iconFolderOpenClass);
                var subtree = $(this).siblings('ul');
                icon.removeClass(iconFolderOpenClass).removeClass(iconFolderCloseClass);
                if (expanded) {
                    if (typeof subtree != 'undefined') {
                        subtree.slideUp({ duration: 100 });
                    }
                    icon.addClass(iconFolderCloseClass);
                } else {
                    if (typeof subtree != 'undefined') {
                        subtree.slideDown({ duration: 100 });
                    }
                    icon.addClass(iconFolderOpenClass);
                }
            });
            // 右键展开下属所有目录
            $('#categories a[data-role="directory"]').bind("contextmenu", function(event){
                event.preventDefault();
                
                var icon = $(this).children('.fa');
                var expanded = icon.hasClass(iconFolderOpenClass);
                var listNode = $(this).siblings('ul');
                var subtrees = $.merge(listNode.find('li ul'), listNode);
                var icons = $.merge(listNode.find('.fa'), icon);
                icons.removeClass(iconFolderOpenClass).removeClass(iconFolderCloseClass);
                if(expanded) {
                    subtrees.slideUp({ duration: 100 });
                    icons.addClass(iconFolderCloseClass);
                } else {
                    subtrees.slideDown({ duration: 100 });
                    icons.addClass(iconFolderOpenClass);
                }
            })
            // 展开关闭所有目录按钮
            $(document).on('click', '#allExpand', function (event) {
                event.preventDefault();
                
                var icon = $(this).children('.fa');
                var expanded = icon.hasClass(iconAllExpandClass);
                icon.removeClass(iconAllExpandClass).removeClass(iconAllPackClass);
                if(expanded) {
                    $('#sidebar .fa.fa-folder').removeClass('fa-folder').addClass('fa-folder-open')
                    $('#categories li ul').slideDown({ duration: 100 });
                    icon.addClass(iconAllPackClass);
                } else {
                    $('#sidebar .fa.fa-folder-open').removeClass('fa-folder-open').addClass('fa-folder')
                    $('#categories li ul').slideUp({ duration: 100 });
                    icon.addClass(iconAllExpandClass);
                }
            });  
        });
    </script>

    
    <div id="toTop" class="fa fa-angle-up"></div>
</aside>
            
            <section id="main"><article id="post-数据库/redis/1-redis-好-使用场景" class="article article-type-post" itemscope itemprop="blogPost">
    <div class="article-inner">
        
        
            <header class="article-header">
                
                    <div class="article-meta">
                        
    <div class="article-category">
    	<i class="fa fa-folder"></i>
        <a class="article-category-link" href="/gitee-internal-blog/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/">数据库</a><i class="fa fa-angle-right"></i><a class="article-category-link" href="/gitee-internal-blog/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/">redis</a>
    </div>

                        
    <div class="article-tag">
        <i class="fa fa-tag"></i>
        <a class="tag-link-link" href="/gitee-internal-blog/tags/redis/" rel="tag">redis</a>
    </div>

                        
    <div class="article-date">
        <i class="fa fa-calendar"></i>
        <a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/1-redis-%E5%A5%BD-%E4%BD%BF%E7%94%A8%E5%9C%BA%E6%99%AF/">
            <time datetime="2021-09-04T08:06:22.000Z" itemprop="datePublished">2021-09-04</time>
        </a>
    </div>


                        
                            <i class="fa fa-bar-chart"></i>
                            <span id="busuanzi_container_site_pv"><span id="busuanzi_value_page_pv"></span></span>    
                        
                        
                            <div class="article-meta-button">
                                <a target="_blank" rel="noopener" href='https://github.com/zthxxx/Wiki-site/raw/writing/source/_posts/数据库/redis/1-redis-好-使用场景.md'> Source </a>
                            </div>
                            <div class="article-meta-button">
                                <a target="_blank" rel="noopener" href='https://github.com/zthxxx/Wiki-site/edit/writing/source/_posts/数据库/redis/1-redis-好-使用场景.md'> Edit </a>
                            </div>
                            <div class="article-meta-button">
                                <a target="_blank" rel="noopener" href='https://github.com/zthxxx/Wiki-site/commits/writing/source/_posts/数据库/redis/1-redis-好-使用场景.md'> History </a>
                            </div>
                        
                    </div>
                
                
    
        <h1 class="article-title" itemprop="name">
            1-redis-好-使用场景
        </h1>
    

            </header>
        
        
        <div class="article-entry" itemprop="articleBody">
        
        
            
                <div id="toc" class="toc-article">
                <strong class="toc-title">Catalogue</strong>
                    <ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#redis"><span class="toc-number">1.</span> <span class="toc-text">redis</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%9F%A5%E8%AF%86%E7%82%B9%E8%84%91%E5%9B%BE"><span class="toc-number">1.1.</span> <span class="toc-text">知识点脑图</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81"><span class="toc-number">1.2.</span> <span class="toc-text">分布式锁</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%B8%BA%E4%BB%80%E4%B9%88%E9%9C%80%E8%A6%81%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81"><span class="toc-number">1.2.1.</span> <span class="toc-text">为什么需要分布式锁</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%80%8E%E6%A0%B7%E5%AE%9E%E7%8E%B0"><span class="toc-number">1.2.2.</span> <span class="toc-text">怎样实现</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%81%BF%E5%85%8D%E6%AD%BB%E9%94%81"><span class="toc-number">1.2.3.</span> <span class="toc-text">避免死锁</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%97%AE%E9%A2%98"><span class="toc-number">1.2.4.</span> <span class="toc-text">问题</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#1%EF%BC%89%E9%94%81%E8%B6%85%E6%97%B6%E9%87%8A%E6%94%BE%E4%BA%86%E5%88%AB%E4%BA%BA%E5%AE%B6%E9%94%81"><span class="toc-number">1.2.4.1.</span> <span class="toc-text">1）锁超时释放了别人家锁</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#2%EF%BC%89%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81%E5%9C%A8%E5%A4%9A%E7%82%B9%E9%97%AE%E9%A2%98"><span class="toc-number">1.2.4.2.</span> <span class="toc-text">2）分布式锁在多点问题</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%BB%B6%E6%97%B6%E9%98%9F%E5%88%97%EF%BC%88%E5%B0%8F%E7%B3%BB%E7%BB%9F%EF%BC%8C%E6%97%A0ack%EF%BC%89"><span class="toc-number">1.3.</span> <span class="toc-text">延时队列（小系统，无ack）</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%8D%E5%9B%BEbitmap"><span class="toc-number">1.4.</span> <span class="toc-text">位图bitmap</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%AD%BE%E5%88%B0%E8%AE%B0%E5%BD%95"><span class="toc-number">1.4.1.</span> <span class="toc-text">签到记录</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%BB%9F%E8%AE%A1%E6%9C%88%E6%B4%BB"><span class="toc-number">1.4.2.</span> <span class="toc-text">统计月活</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#HyperLogLog%EF%BC%88%E4%B8%8D%E5%87%86%E7%A1%AE%E7%9A%84set%EF%BC%89"><span class="toc-number">1.5.</span> <span class="toc-text">HyperLogLog（不准确的set）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#pv"><span class="toc-number">1.5.1.</span> <span class="toc-text">pv</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#uv"><span class="toc-number">1.5.2.</span> <span class="toc-text">uv</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%B8%83%E9%9A%86%E8%BF%87%E6%BB%A4%E5%99%A8%EF%BC%88redis4%EF%BC%89"><span class="toc-number">1.6.</span> <span class="toc-text">布隆过滤器（redis4）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%8E%A8%E8%8D%90%E4%B8%8D%E9%87%8D%E5%A4%8D%E5%86%85%E5%AE%B9"><span class="toc-number">1.6.1.</span> <span class="toc-text">推荐不重复内容</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%9E%83%E5%9C%BE%E9%82%AE%E4%BB%B6%E8%BF%87%E6%BB%A4"><span class="toc-number">1.6.2.</span> <span class="toc-text">垃圾邮件过滤</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Bloomfilter%E7%9A%84%E5%9C%BA%E6%99%AF"><span class="toc-number">1.6.3.</span> <span class="toc-text">Bloomfilter的场景</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%A4%8D%E6%9D%82%E5%BA%A6"><span class="toc-number">1.6.4.</span> <span class="toc-text">复杂度</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#tps%E5%92%8Cmysql%E7%9A%84%E5%AF%B9%E6%AF%94"><span class="toc-number">1.7.</span> <span class="toc-text">tps和mysql的对比</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Redis%EF%BC%88tps-5%E4%B8%87-30%E4%B8%87%EF%BC%89"><span class="toc-number">1.7.1.</span> <span class="toc-text">Redis（tps 5万-30万）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#MySQL%EF%BC%88tps-4000%EF%BC%89"><span class="toc-number">1.7.2.</span> <span class="toc-text">MySQL（tps 4000）</span></a></li></ol></li></ol></li></ol>
                </div>
            
        
        
            <h1 id="redis"><a href="#redis" class="headerlink" title="redis"></a>redis</h1><p>Redis 定位是一个内存数据库，正是由于内存的快速访问特性，才使得Redis能够有如此高的性能，才使得Redis能够轻松处理大量复杂的数据结构</p>
<p>缓存只是他最简单和基础的功能罢了，哨兵，集群，分布式锁，延时队列，位图，HyperLogLog，布隆过滤器，限流，GeoHash（附近的人）</p>
<h2 id="知识点脑图"><a href="#知识点脑图" class="headerlink" title="知识点脑图"></a>知识点脑图</h2><img src="/gitee-internal-blog/images/redis-知识点脑图.jpg"/>



<h2 id="分布式锁"><a href="#分布式锁" class="headerlink" title="分布式锁"></a>分布式锁</h2><h3 id="为什么需要分布式锁"><a href="#为什么需要分布式锁" class="headerlink" title="为什么需要分布式锁"></a>为什么需要分布式锁</h3><p>多系统写作，竞争共享资源，难免就要了</p>
<h3 id="怎样实现"><a href="#怎样实现" class="headerlink" title="怎样实现"></a>怎样实现</h3><p>分布式锁本质上要实现的目标就是在 Redis 里面占一个“茅坑”，当别的进程也要来占时，发现已经有人蹲在那里了，就只好放弃或者稍后再试。</p>
<p>占坑一般是使用 setnx(set if not exists) 指令，只允许被一个客户端占坑，先来先占， 用完了，再调用 del 指令释放茅坑。</p>
<p>但是引入后会有问题，原子性，怎么解决，就比如setnx成功，设置失效时间expire的时候失败，怎么办？</p>
<p>当时出现了贼多的第三方插件，作者为了解决这个乱象，就在Redis 2.8 版本中作者加入了 set 指令的扩展参数：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">set  aobing ture  ex 5 nx</span><br><span class="line">del  aobing</span><br></pre></td></tr></table></figure>

<p>但是这样还是有问题超时问题，可重入问题等等，这个时候，第三方的一些插件就横空出世了，Redission ，Jedis，他们的底层我就不过多描述了，都是通过lua脚本去保证的，大致逻辑跟我们代码实现是差不多的。</p>
<p>就比如去删除的时候，去校验是否当前线程锁定的，就把比较和删除这样一些动作都放到一起了。</p>
<ol>
<li><strong>基于 MySQL 中的锁</strong>：MySQL 本身有自带的悲观锁 <code>for update</code> 关键字，也可以自己实现悲观/乐观锁来达到目的；</li>
<li><strong>基于 Zookeeper 有序节点</strong>：Zookeeper 允许临时创建有序的子节点，这样客户端获取节点列表时，就能够当前子节点列表中的序号判断是否能够获得锁；</li>
<li><strong>基于 Redis 的单线程</strong>：由于 Redis 是单线程，所以命令会以串行的方式执行，并且本身提供了像 <code>SETNX(set if not exists)</code> 这样的指令，本身具有互斥性；</li>
</ol>
<h3 id="避免死锁"><a href="#避免死锁" class="headerlink" title="避免死锁"></a>避免死锁</h3><p>死锁四个要求，解除其中一个。所以redis 2.6.12之后，setnx和expire原子性执行了，有了超时。set lock true ex 10 nx</p>
<h3 id="问题"><a href="#问题" class="headerlink" title="问题"></a>问题</h3><h4 id="1）锁超时释放了别人家锁"><a href="#1）锁超时释放了别人家锁" class="headerlink" title="1）锁超时释放了别人家锁"></a>1）锁超时释放了别人家锁</h4><p><strong>锁过期时间不好评估</strong></p>
<p>先设置一个过期时间，开启一个守护线程，定时检测失效时间，快要过期就自动对锁进行续期。（怎么判断是否需要续期，可能续几次之后就不续咯）。redisson就采用了自动续期避免锁过期，这个守护线程我们一般也叫做“看门狗”线程。</p>
<p><strong>避免解了别人锁</strong> </p>
<p><strong>将锁的 <code>value</code> 值设置为一个随机数</strong>，释放锁时先匹配随机数是否一致，然后再删除 key，这是为了 <strong>确保当前线程占有的锁不会被其他线程释放</strong>，除非这个锁是因为过期了而被服务器自动释放的。</p>
<h4 id="2）分布式锁在多点问题"><a href="#2）分布式锁在多点问题" class="headerlink" title="2）分布式锁在多点问题"></a>2）分布式锁在多点问题</h4><p>如果 Redis 采用单机部署模式，那就意味着当 Redis 故障了，就会导致整个服务不可用。</p>
<p>但是多节点时，master死了就有各种问题，所以<strong>RedLock 红锁</strong> 的算法 *(Redission 同 Jedis)*：</p>
<p>2个前提：</p>
<ol>
<li>不在需要从库，哨兵，只部署主库</li>
<li>至少5个主库</li>
</ol>
<p>流程：</p>
<ol>
<li>客户端先获取“当前时间戳t1”</li>
<li>客户端依次向5个实例发起加锁请求，每个设置超时时间。加锁失败，立即向下一个实例申请。</li>
<li>从&gt;=3个以上加锁成功，再次获取“当前时间戳t2”，如果t2-t1&lt;锁的过期时间，认为加锁成功。</li>
</ol>
<h2 id="延时队列（小系统，无ack）"><a href="#延时队列（小系统，无ack）" class="headerlink" title="延时队列（小系统，无ack）"></a>延时队列（小系统，无ack）</h2><p>Redis 的消息队列不是专业的消息队列，它没有非常多的高级特性，没有 ack 保证，如果对消息的可靠性有着极致的追求，那么它就不适合使用。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">rpush notify-queue apple banana pear</span><br><span class="line">(integer) 3</span><br><span class="line">&gt; llen notify-queue</span><br><span class="line">(integer) 3</span><br><span class="line">&gt; lpop notify-queue</span><br><span class="line">&quot;apple&quot;</span><br><span class="line">&gt; llen notify-queue</span><br><span class="line">(integer) 2</span><br><span class="line">&gt; lpop notify-queue</span><br><span class="line">&quot;banana&quot;</span><br><span class="line">&gt; llen notify-queue</span><br><span class="line">(integer) 1</span><br><span class="line">&gt; lpop notify-queue</span><br><span class="line">&quot;pear&quot;</span><br><span class="line">&gt; llen notify-queue</span><br><span class="line">(integer) 0</span><br><span class="line">&gt; lpop notify-queue</span><br><span class="line">(nil)</span><br></pre></td></tr></table></figure>

<p>如果队列空了，客户端就会陷入 pop 的死循环，不停地 pop，没有数据，接着再 pop，又没有数据，这就是浪费生命的空轮询。</p>
<p>空轮询不但拉高了客户端的 CPU，redis 的 QPS 也会被拉高，如果这样空轮询的客户端有几十来个，Redis 的慢查询可能会显著增多。</p>
<p>解决方式很简单，让线程睡一秒 Thread.sleep(1000)</p>
<p>list有个blpop(block)用来当list为空时阻塞住，有值再同步回客户端，这样就不用客户端轮询了。</p>
<p>Redis在我开发的一些简易后台我确实有用到，因为我觉得没必要接入消息队列中间件，大家平时开发小系统可以试试。</p>
<h2 id="位图bitmap"><a href="#位图bitmap" class="headerlink" title="位图bitmap"></a>位图bitmap</h2><h3 id="签到记录"><a href="#签到记录" class="headerlink" title="签到记录"></a>签到记录</h3><p>比如用户一年的签到记录，签了是 1，没签是 0，要记录 365 天。如果使用普通的 key/value，每个用户要记录 365 个，当用户上亿的时候，需要的存储空间是惊人的。</p>
<p>为了解决这个问题，Redis 提供了位图数据结构，这样每天的签到记录只占据一个位，365 天就是 365 个位，46 个字节 (一个稍长一点的字符串) 就可以完全容纳下，这就大大节约了存储空间。</p>
<p>位图不是特殊的数据结构，它的内容其实就是普通的字符串，也就是 byte 数组。</p>
<p>key 可以设置为 前缀:用户id:年月   譬如 setbit sign:123:1909 0 1</p>
<p>代表用户ID=123签到，签到的时间是19年9月份，0代表该月第一天，1代表签到了</p>
<p>第二天没有签到，无需处理，系统默认为0</p>
<p>第三天签到  setbit sign:123:1909 2 1</p>
<p>可以查看一下目前的签到情况，显示第一天和第三天签到了，前8天目前共签到了2天</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">127.0.0.1:6379&gt; setbit sign:123:1909 0 1</span><br><span class="line">0</span><br><span class="line">127.0.0.1:6379&gt; setbit sign:123:1909 2 1</span><br><span class="line">0</span><br><span class="line">127.0.0.1:6379&gt; getbit sign:123:1909 0</span><br><span class="line">1</span><br><span class="line">127.0.0.1:6379&gt; getbit sign:123:1909 1</span><br><span class="line">0</span><br><span class="line">127.0.0.1:6379&gt; getbit sign:123:1909 2</span><br><span class="line">1</span><br><span class="line">127.0.0.1:6379&gt; getbit sign:123:1909 3</span><br><span class="line">0</span><br><span class="line">127.0.0.1:6379&gt; bitcount sign:123:1909 0 0</span><br><span class="line">2</span><br></pre></td></tr></table></figure>

<h3 id="统计月活"><a href="#统计月活" class="headerlink" title="统计月活"></a>统计月活</h3><p>每个用户会都在这个位图的一个确定位置上，0 表示不活跃，1 表示活跃。然后到月底遍历一次位图就可以得到月度活跃用户数。</p>
<h2 id="HyperLogLog（不准确的set）"><a href="#HyperLogLog（不准确的set）" class="headerlink" title="HyperLogLog（不准确的set）"></a>HyperLogLog（不准确的set）</h2><h3 id="pv"><a href="#pv" class="headerlink" title="pv"></a>pv</h3><p>这个计数器的 key 后缀加上当天的日期。这样来一个请求，incrby 一次，最终就可以统计出所有的 PV 数据。</p>
<h3 id="uv"><a href="#uv" class="headerlink" title="uv"></a>uv</h3><ol>
<li><p>set</p>
<p>为每一个页面一个独立的 set 集合来存储所有当天访问过此页面的用户 ID。</p>
<p>当一个请求过来时，我们使用 sadd 将用户 ID 塞进去就可以了。</p>
<p>通过 scard 可以取出这个集合的大小，这个数字就是这个页面的 UV 数据。没错，这是一个非常简单的方案。</p>
<p>但是，如果你的页面访问量非常大，比如一个爆款页面几千万的 UV，你需要一个很大的 set 集合来统计，这就非常浪费空间。</p>
</li>
<li><p>HyperLogLog (不需要太精确)提供了两个指令 pfadd 和 pfcount，根据字面意义很好理解，一个是增加计数，一个是获取计数。</p>
<p>pfadd 用法和 set 集合的 sadd 是一样的，来一个用户 ID，就将用户 ID 塞进去就是，pfcount 和 scard 用法是一样的，直接获取计数值。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">127.0.0.1:6379&gt; pfadd codehole user1</span><br><span class="line">(integer) 1</span><br><span class="line">127.0.0.1:6379&gt; pfcount codehole</span><br><span class="line">(integer) 1</span><br><span class="line">127.0.0.1:6379&gt; pfadd codehole user2</span><br><span class="line">(integer) 1</span><br><span class="line">127.0.0.1:6379&gt; pfcount codehole</span><br><span class="line">(integer) 2</span><br><span class="line">127.0.0.1:6379&gt; pfadd codehole user3</span><br><span class="line">(integer) 1</span><br><span class="line">127.0.0.1:6379&gt; pfcount codehole</span><br><span class="line">(integer) 3</span><br><span class="line">127.0.0.1:6379&gt; pfadd codehole user4</span><br><span class="line">(integer) 1</span><br><span class="line">127.0.0.1:6379&gt; pfcount codehole</span><br><span class="line">(integer) 4</span><br><span class="line">127.0.0.1:6379&gt; pfadd codehole user5</span><br><span class="line">(integer) 1</span><br><span class="line">127.0.0.1:6379&gt; pfcount codehole</span><br><span class="line">(integer) 5</span><br><span class="line">127.0.0.1:6379&gt; pfadd codehole user6</span><br><span class="line">(integer) 1</span><br><span class="line">127.0.0.1:6379&gt; pfcount codehole</span><br><span class="line">(integer) 6</span><br><span class="line">127.0.0.1:6379&gt; pfadd codehole user7 user8 user9 user10</span><br><span class="line">(integer) 1</span><br><span class="line">127.0.0.1:6379&gt; pfcount codehole</span><br><span class="line">(integer) 10</span><br></pre></td></tr></table></figure></li>
</ol>
<h2 id="布隆过滤器（redis4）"><a href="#布隆过滤器（redis4）" class="headerlink" title="布隆过滤器（redis4）"></a>布隆过滤器（redis4）</h2><p>HyperLogLog 数据结构来进行估数，它非常有价值，可以解决很多精确度不高的统计需求。</p>
<p>但是如果我们想知道某一个值是不是已经在 HyperLogLog 结构里面了，它就无能为力了，它只提供了 pfadd 和 pfcount 方法，没有提供 pfcontains 这种方法。</p>
<p>平时用到的 HBase、Cassandra 还有 LevelDB、RocksDB 内部都有布隆过滤器结构，布隆过滤器可以显著降低数据库的 IO 请求数量。当用户来查询某个 row 时，可以先通过内存中的布隆过滤器过滤掉大量不存在的 row 请求，然后再去磁盘进行查询。</p>
<p>布隆过滤器的error_rate越小，需要的存储空间就越大，对于不需要过于精确的场合，error_rate设置稍大一点也无伤大雅。比如在新闻去重上而言，误判率高一点只会让小部分文章不能让合适的人看到，文章的整体阅读量不会因为这点误判率就带来巨大的改变。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">127.0.0.1:6379&gt; bf.add codehole user1</span><br><span class="line">(integer) 1</span><br><span class="line">127.0.0.1:6379&gt; bf.add codehole user2</span><br><span class="line">(integer) 1</span><br><span class="line">127.0.0.1:6379&gt; bf.add codehole user3</span><br><span class="line">(integer) 1</span><br><span class="line">127.0.0.1:6379&gt; bf.exists codehole user1</span><br><span class="line">(integer) 1</span><br><span class="line">127.0.0.1:6379&gt; bf.exists codehole user2</span><br><span class="line">(integer) 1</span><br><span class="line">127.0.0.1:6379&gt; bf.exists codehole user3</span><br><span class="line">(integer) 1</span><br><span class="line">127.0.0.1:6379&gt; bf.exists codehole user4</span><br><span class="line">(integer) 0</span><br><span class="line">127.0.0.1:6379&gt; bf.madd codehole user4 user5 user6</span><br><span class="line">1) (integer) 1</span><br><span class="line">2) (integer) 1</span><br><span class="line">3) (integer) 1</span><br><span class="line">127.0.0.1:6379&gt; bf.mexists codehole user4 user5 user6 user7</span><br><span class="line">1) (integer) 1</span><br><span class="line">2) (integer) 1</span><br><span class="line">3) (integer) 1</span><br><span class="line">4) (integer) 0</span><br></pre></td></tr></table></figure>

<h3 id="推荐不重复内容"><a href="#推荐不重复内容" class="headerlink" title="推荐不重复内容"></a>推荐不重复内容</h3><h3 id="垃圾邮件过滤"><a href="#垃圾邮件过滤" class="headerlink" title="垃圾邮件过滤"></a>垃圾邮件过滤</h3><h3 id="Bloomfilter的场景"><a href="#Bloomfilter的场景" class="headerlink" title="Bloomfilter的场景"></a>Bloomfilter的场景</h3><ol>
<li>数据库防止穿库 Google Bigtable，Apache HBase和Apache Cassandra以及Postgresql 使用BloomFilter来减少不存在的行或列的磁盘查找。避免代价高昂的磁盘查找会大大提高数据库查询操作的性能。</li>
<li>缓存宕机。减少call去数据库。</li>
<li>web拦截器。拦截相同请求。</li>
<li>恶意地址检测</li>
<li>比特币加速钱包同步（在比特币网络中，存在一些轻节点，这些轻节点并不保存所有的区块和交易，而只是保存自己感兴趣的交易。当轻节点向全节点同步数据时，它发送的不是所有的交易列表，因为这可能会有成千上万条，甚至更多。取而代之，它发送的是通过该交易列表所计算出的一个布隆过滤器。全节点通过计算本地的区块，找到匹配的交易并发送给轻节点。）</li>
</ol>
<h3 id="复杂度"><a href="#复杂度" class="headerlink" title="复杂度"></a>复杂度</h3><p><strong>时间复杂度</strong><br> 由于需要计算k次的哈希，需要的时间复杂度为O(k)，而计算出对应的索引后，可以进行直接地址访问，需要的时间复杂度为O(1)，所以总的时间复杂度为O(k)。</p>
<p><strong>空间复杂度</strong><br> 由于需要长度为m的二进制数据，所以空间复杂度为O(m)，但是由于数据的基本单位是位，假设为了处理100万条数据，为了降低假阳性的概率，我们使用长度为1000万的二进制数组，所需的内存空间为10,000,000/8/1024/1024=1.2M内存空间。</p>
<h2 id="tps和mysql的对比"><a href="#tps和mysql的对比" class="headerlink" title="tps和mysql的对比"></a>tps和mysql的对比</h2><p><a target="_blank" rel="noopener" href="https://database.51cto.com/art/201910/604007.htm">https://database.51cto.com/art/201910/604007.htm</a></p>
<h3 id="Redis（tps-5万-30万）"><a href="#Redis（tps-5万-30万）" class="headerlink" title="Redis（tps 5万-30万）"></a><strong>Redis</strong>（tps 5万-30万）</h3><p>进入 Redis[1] 官网，使用如下步骤安装。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ wget http:&#x2F;&#x2F;download.redis.io&#x2F;releases&#x2F;redis-5.0.5.tar.gz  $ tar xzf redis-5.0.5.tar.gz  $ cd redis-5.0.5  $ make </span><br></pre></td></tr></table></figure>

<p>启动服务</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ src&#x2F;redis-server </span><br></pre></td></tr></table></figure>

<p>运行 Redis 自带的基准测试工具，运行 set，get 1000000 次，1s 后退出并显示数据</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ cd src    $ .&#x2F;redis-benchmark -n 1000000 -t set,get -q </span><br></pre></td></tr></table></figure>

<p>数据显示如下，结果为 SET 48009，GET 56960。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">SET: 48009.98 requests per second  GET: 56960.59 requests per second </span><br></pre></td></tr></table></figure>

<p>当然这数据是没有使用 pipeline 的情况下，那么使用了 pipeline 又是什么场景呢？运行命令如下，运行 set，get 1000000 次，每次发送 200 个请求到服务端，1s 后退出并显示数据</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ cd src    $ .&#x2F;redis-benchmark -n 1000000 -t set,get -P 200 -q </span><br></pre></td></tr></table></figure>

<p>数据显示如下，结果为 SET 315258，GET 330797。这里你可以自行调整 -P 的数值，上升到 30000 上下保持平稳，所以如下数据是理论上最佳的测试数据。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">SET: 315258.53 requests per second  GET: 330797.22 requests per second </span><br></pre></td></tr></table></figure>

<p>好的，到这里我们就知道了，Redis 的大致数据为 50000 - 300000，那么我们赶紧看看 MySQL 呗？</p>
<h3 id="MySQL（tps-4000）"><a href="#MySQL（tps-4000）" class="headerlink" title="MySQL（tps 4000）"></a><strong>MySQL</strong>（tps 4000）</h3><p>可前往 MySQL[2] 官网自行安装 MySQL，我的服务环境是 Ubuntu，所以我的安装命令如下</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo apt-get install mysql-server  $ sudo apt-get install mysql-client </span><br></pre></td></tr></table></figure>

<p>我测试 MySQL 的性能使用 sysbench[3] 工具，所以接下来我们需要安装一下。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ url -s https:&#x2F;&#x2F;packagecloud.io&#x2F;install&#x2F;repositories&#x2F;akopytov&#x2F;sysbench&#x2F;script.deb.sh | sudo bash  sudo apt -y install sysbench </span><br></pre></td></tr></table></figure>

<p>安装 sysbench 以后在 /usr/share/sysbench/ 目录下面会自带一些测试脚本，直接可以使用，我们只需要手动创建一个名为 benchmark 的 database，然后运行如下命令，准备数据-&gt;测试数据</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sysbench &#x2F;usr&#x2F;share&#x2F;sysbench&#x2F;oltp_read_write.lua --mysql-user&#x3D;root --mysql-password&#x3D;root --mysql-db&#x3D;benchmark --tables&#x3D;10 --table-size&#x3D;1000000 --events&#x3D;100000000 --report-interval&#x3D;10 --threads&#x3D;4 --time&#x3D;300 prepare  sysbench &#x2F;usr&#x2F;share&#x2F;sysbench&#x2F;oltp_read_write.lua --mysql-user&#x3D;root --mysql-password&#x3D;root --mysql-db&#x3D;benchmark --tables&#x3D;10 --table-size&#x3D;1000000 --events&#x3D;100000000 --report-interval&#x3D;10 --threads&#x3D;4 --time&#x3D;300 run </span><br></pre></td></tr></table></figure>

<p>运行完成以后数据如下</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[ 10s ] thds: 4 tps: 198.84 qps: 3982.73 (r&#x2F;w&#x2F;o: 2788.48&#x2F;796.17&#x2F;398.08) lat (ms,95%): 54.83 err&#x2F;s: 0.00 reconn&#x2F;s: 0.00  [ 20s ] thds: 4 tps: 174.38 qps: 3486.62 (r&#x2F;w&#x2F;o: 2440.73&#x2F;697.12&#x2F;348.76) lat (ms,95%): 52.89 err&#x2F;s: 0.00 reconn&#x2F;s: 0.00  [ 30s ] thds: 4 tps: 204.54 qps: 4089.94 (r&#x2F;w&#x2F;o: 2863.12&#x2F;817.75&#x2F;409.07) lat (ms,95%): 55.82 err&#x2F;s: 0.00 reconn&#x2F;s: 0.00  [ 40s ] thds: 4 tps: 214.98 qps: 4299.59 (r&#x2F;w&#x2F;o: 3009.71&#x2F;859.92&#x2F;429.96) lat (ms,95%): 49.21 err&#x2F;s: 0.00 reconn&#x2F;s: 0.00  [ 50s ] thds: 4 tps: 188.31 qps: 3767.98 (r&#x2F;w&#x2F;o: 2637.12&#x2F;754.24&#x2F;376.62) lat (ms,95%): 52.89 err&#x2F;s: 0.00 reconn&#x2F;s: 0.00  [ 60s ] thds: 4 tps: 228.00 qps: 4559.06 (r&#x2F;w&#x2F;o: 3191.64&#x2F;911.41&#x2F;456.01) lat (ms,95%): 49.21 err&#x2F;s: 0.00 reconn&#x2F;s: 0.00 </span><br></pre></td></tr></table></figure>

<p>叮叮叮，是不是发现了什么？数据显示 MySQL 的 QPS 为 4000 左右浮动。</p>
<p><strong>结论</strong></p>
<p>此时一句话脱口而出重剑无锋，大巧不工，Redis 的优秀性能真的不是擂的，正如 《Redis in Action》中提到，Redis 的性能会是普通关系型数据库的 10 - 100 倍，如果你不是亲眼所见也不敢相信？那么你可以亲自动手试试喽？</p>
<p>PS: 当然并不是说因此就不用 MySQL 了，他们的特质不同决定了他们的场景，MySQL 的 InnoDB 引擎是的他有非常健全的事务系统，还是各领风骚哦。</p>

            </div>
        
        <footer class="article-footer">
        </footer>
    </div>
</article>


    
<nav id="article-nav">
    
        <a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/11-redis-%E5%8F%AF%E7%94%A8%E6%80%A7-mysql%E4%B8%80%E8%87%B4%E6%80%A7%E9%97%AE%E9%A2%98/" id="article-nav-newer" class="article-nav-link-wrap">
            <strong class="article-nav-caption">Newer</strong>
            <div class="article-nav-title">
                
                    11-redis-可用性-mysql一致性问题
                
            </div>
        </a>
    
    
        <a href="/gitee-internal-blog/2021/09/04/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/2-redis-%E5%BF%AB-%E5%86%85%E5%AD%98%E8%80%97%E5%B0%BD%E5%90%8E%E4%BC%9A%E6%80%8E%E6%A0%B7/" id="article-nav-older" class="article-nav-link-wrap">
            <strong class="article-nav-caption">Older</strong>
            <div class="article-nav-title">2-redis-快-内存耗尽后会怎样</div>
        </a>
    
</nav>





    
    




<!-- baidu url auto push script -->
<script type="text/javascript">
    !function(){var e=/([http|https]:\/\/[a-zA-Z0-9\_\.]+\.baidu\.com)/gi,r=window.location.href,o=document.referrer;if(!e.test(r)){var n="//api.share.baidu.com/s.gif";o?(n+="?r="+encodeURIComponent(document.referrer),r&&(n+="&l="+r)):r&&(n+="?l="+r);var t=new Image;t.src=n}}(window);
</script>     
</section>
        </div>
        <footer id="footer">
    <div class="outer">
        <div id="footer-info" class="inner">
            Johnny &copy; 2023 
            <a rel="license noopener" target="_blank" href="http://creativecommons.org/licenses/by-nc-nd/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-nd/4.0/80x15.png" /></a>
            <br> Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>. Theme - <a target="_blank" rel="noopener" href="https://github.com/zthxxx/hexo-theme-Wikitten">wikitten</a>
            
                <br>
                <span id="busuanzi_container_site_pv"><i class="fa fa-eye"></i> <span id="busuanzi_value_site_pv"></span></span>
                &nbsp;|&nbsp;
                <span id="busuanzi_container_site_pv"><i class="fa fa-user"></i> <span id="busuanzi_value_site_uv"></span></span>
            
        </div>
    </div>
</footer>

        

    
        
<script src="/gitee-internal-blog/libs/lightgallery/js/lightgallery.min.js"></script>

        
<script src="/gitee-internal-blog/libs/lightgallery/js/lg-thumbnail.min.js"></script>

        
<script src="/gitee-internal-blog/libs/lightgallery/js/lg-pager.min.js"></script>

        
<script src="/gitee-internal-blog/libs/lightgallery/js/lg-autoplay.min.js"></script>

        
<script src="/gitee-internal-blog/libs/lightgallery/js/lg-fullscreen.min.js"></script>

        
<script src="/gitee-internal-blog/libs/lightgallery/js/lg-zoom.min.js"></script>

        
<script src="/gitee-internal-blog/libs/lightgallery/js/lg-hash.min.js"></script>

        
<script src="/gitee-internal-blog/libs/lightgallery/js/lg-share.min.js"></script>

        
<script src="/gitee-internal-blog/libs/lightgallery/js/lg-video.min.js"></script>

    
    
        
<script src="/gitee-internal-blog/libs/justified-gallery/jquery.justifiedGallery.min.js"></script>

    
    
        <script type="text/x-mathjax-config">
    MathJax.Hub.Config({
        tex2jax: {
            inlineMath: [ ["$","$"], ["\\(","\\)"] ],
            skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code'],
            processEscapes: true,
            TeX: {
                equationNumbers: {
                  autoNumber: 'AMS'
                }
            }
        }
    });
    MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax();
        for (var i = 0; i < all.length; ++i)
            all[i].SourceElement().parentNode.className += ' has-jax';
    });
</script>
<script async src="//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
    



<!-- Custom Scripts -->

<script src="/gitee-internal-blog/js/main.js"></script>


    </div>
</body>
</html>